/**
 *  jQuery.jsonengine
 */
(function($) {
	$.jsonengine = function() {	};
	$.jsonengine.version = '03-02-2011';
})(jQuery);

/**
 *  jQuery.jsonengine.utils
 */
(function($) {
	$.jsonengine.utils = function() { };
	/**
	 * jsonデータをhtmlリスト形式へ
	 */
	$.jsonengine.utils.json2htmlList = function(json, header) {
		var h = '';
		if(header) h = header;
		if (!json) {
			return json;
		} else if (Object.prototype.toString.call(json)=='[object Object]') {
			var dl = $('<dl class="' + h + 'object_Object">');
			for ( var key in json) {
				dl.append($('<dt class="' + h + key + '">').html(key));
				dl.append($('<dd class="' + h + key + '">').html($.jsonengine.utils.json2htmlList(json[key])));
			}
			return dl;
		} else if (Object.prototype.toString.call(json)=='[object Array]') {
			var ol = $('<ol class="' + h + 'object_Array">');
			var json_length = json.length;
			for ( var i = 0; i < json_length; i++) { //TODO このクラス名は変な感じするので後で治す。
				ol.append($('<li class="' + h + 'value">').html($.jsonengine.utils.json2htmlList(json[i])));
			}
			return ol;
		} else {
			return json;
		}
	};
	/**
	 *  TODO htmlリストをjsonデータ形式へ
	 */
	$.jsonengine.utils.htmlList2json = function(html, header) {
		var h = '';
		if(header) h = header;
		if (!html) {
			return html;
		} else {
			return html;
		}
	};
//	/**
//	 *  example: valueFromHtmlList( $($.jsonengine.utils.json2htmlList(json)).find('.key').eq(0) );
//	 */
//	$.jsonengine.utils.valueFromHtmlList = function(key){
//		if(!key) return key;
//		var nextNode = function(node) {
//			var n;
//			if (n = node.firstChild) return n;
//			do if (n = node.nextSibling) return n; while (node = node.parentNode);
//			return null;
//		};
//		var e = nextNode(nextNode(key)).firstChild;
//		if(!e) return e;
//		if(Object.prototype.toString.call(e)==='[object Text]'){
//			return e.nodeValue;
//		} else {
//			return e;
//		}
//	};
})(jQuery);

/**
 *  jQuery.fn.jsonengine
 */
(function($) {
	$.jsonengine.fn = function() { };
	// htmlに記述された情報からdocType文字列を構築する
	$.jsonengine.fn.docType = function(o) {
		try {
			var docType = o
				.attr('class')
				.match(/_je_.*?\b/)[0]
				.replace('_je_','');
			return docType;
		} catch(e) {
			return null;
		}
	};
	// htmlに記述された情報からURL文字列を構築する
	$.jsonengine.fn.url = function(o) {
		try {
			var docType = $.jsonengine.fn.docType(o);
			if(!docType) return null;
			var query = o
				.find('span.query').eq(0)
				.text()
				.trim();
			return '/_je/' + docType + query;
		} catch(e) {
			return null;
		}
	};
	// $.ajax(option)のラッパー(o, xhr, status, thrown)
	$.jsonengine.fn.ajax = function(option) {
		$.ajax(option);
	};
	// コールバック関数へ引数を渡すための関数 成功用
	$.jsonengine.fn.callback_success = function(o, func) {
		return function(response, status) {
			func(o, response, status);
		};
	};
	// コールバック関数へ引数を渡すための関数 失敗用
	$.jsonengine.fn.callback_error = function(o, func) {
		return function(xhr, status, thrown) {
			func(o, xhr, status, thrown);
		};
	};
	// jsonengineからデータ読み込み成功した際のコールバック関数
	$.jsonengine.fn.success_LOAD = function(o, response, status) {
		var tmp = o.find('span.query');
		o.empty();
		o.append(tmp);
		delete tmp;
		// htmlリストを追加
		var e = $.jsonengine.utils.json2htmlList(response);
		if(e.html()!==''){
			e.addClass('result');
			o.append(e);
		}
	};
	// jsonengineからデータ読み込み失敗した際のコールバック関数
	$.jsonengine.fn.error_LOAD = function(o, xhr, status, thrown){
		o.append($('<div class="error">')
			.append('status:')
				.append($('<span style="color:red;font-weight:bold;">')
					.append(status)));
	};
	// プラグインの定義
	$.fn.extend( {
		// jsonengineから取得したデータを要素内に追加するプラグイン
		_LOAD : function(success, error) {
			for(var i=0; i < this.length; i++){
				// URL文字列を構築
				var url = $.jsonengine.fn.url(this.eq(i));
				// URLが構築出来なかった場合は処理を中止する
				if(!url) return;
				// メソッドタイプ
				var type = 'GET';
				// データ
				var data = '';
				// jsonengineからデータ読み込み成功した際のコールバック関数
				var _success = $.jsonengine.fn.success_LOAD;
				// jsonengineからデータ読み込み失敗した際のコールバック関数
				var _error = $.jsonengine.fn.error_LOAD;
				// 引数にsuccessがある場合
				if (success) _success = success;
				// 引数にerrorがある場合
				if (error) _error = error;
				// $.ajax()用引数の構築
				var option = {
					"type"    : type,
					"url"     : url,
					"data"    : data,
					"success" : $.jsonengine.fn.callback_success(this.eq(i), _success),
					"error"   : $.jsonengine.fn.callback_error(this.eq(i), _error)
				};
				// $.ajax()を実行する
				$.jsonengine.fn.ajax(option);
			}
		},
		_POST : function(success, error) {
		}
	});
})(jQuery);
